package auth_handlers

import (
	"net/http"

	"appengine"
	"appengine/user"

	"model"
	"service_config"
)

type PABUserRequiredHandler func(http.ResponseWriter, *http.Request, *model.User)
type GLoginRequiredHandler func(http.ResponseWriter, *http.Request, *user.User, *model.User)
type PublicHandler func(http.ResponseWriter, *http.Request, *user.User, *model.User)

func PABUserRequired(h PABUserRequiredHandler) http.HandlerFunc {
	// 1. Without g login => redirect to home page(public).
	// 2. With g login but not registered => redirect to home page(public).
	// 3. Private Account Book user => run handler.

	return func(w http.ResponseWriter, r *http.Request) {
		c := appengine.NewContext(r)
		gu := user.Current(c)
		sc := service_config.NewServiceConfAppEngine(c)
		if gu == nil {
			http.Redirect(w, r, sc.HomeURL(), http.StatusMovedPermanently)
			return
		}
		um := model.NewUserModelAppEngine(c)
		pabu, err := um.GetUser(gu.ID)
		if err == model.UserNotRegisteredErr || pabu.Status != model.Active {
			http.Redirect(w, r, sc.HomeURL(), http.StatusMovedPermanently)
			return
		}
		h(w, r, pabu)
	}
}

func GLoginRequired(h GLoginRequiredHandler) http.HandlerFunc {
	// 1. Without g login => redirect to home page.
	// 2. With g login => run handler.
	return func(w http.ResponseWriter, r *http.Request) {
		c := appengine.NewContext(r)
		gu := user.Current(c)
		sc := service_config.NewServiceConfAppEngine(c)
		if gu == nil {
			http.Redirect(w, r, sc.HomeURL(), http.StatusMovedPermanently)
			return
		}
		um := model.NewUserModelAppEngine(c)
		pabu, err := um.GetUser(gu.ID)
		if err == model.UserNotRegisteredErr || pabu.Status != model.Active {
			pabu = nil
		}
		h(w, r, gu, pabu)
	}
}

func Public(h PublicHandler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		c := appengine.NewContext(r)
		gu := user.Current(c)
		var pabu *model.User = nil
		if gu != nil {
			um := model.NewUserModelAppEngine(c)
			u, err := um.GetUser(gu.ID)
			if err == model.UserNotRegisteredErr || u.Status != model.Active {
				pabu = u
			}
		}
		h(w, r, gu, pabu)
	}
}
